#===istalismanplugin===
# -*- coding: utf-8 -*-

# $Revision: 60 $
# $Author: rchiganov@gmail.com $
# $Date: 2013-12-19 16:25:39 +0000 (Thu, 19 Dec 2013) $

# Initial Copyright © 2007 dimichxp <dimichxp@gmail.com>
# Modifications Copyright © 2007 Als <Als@exploit.in>

#---------------------------------------------------------------------------------------------------

import xmpp
import random

#---------------------------------------------------------------------------------------------------

VCARD_PENDING = [ ]
VCARD_OFF = [ u'PHOTO', u'USERID', u'CTRY', u'ROLE' ]
VCARD_EXCEPTION = { u'list': [ u'ADR', u'TEL' ], u'keys': [ u'HOME', u'WORK' ], u'line': { u'FAX': u'NUMBER', u'CELL': u'NUMBER' } }
VCARD_REPLACE = { u'vCard': u'Визитка', u'GENDER': u'Пол', u'TITLE': u'Должность', u'BDAY': u'Д.р.', u'WORK': u'Работа', u'LOCALITY': u'Город', u'COUNTRY': u'Страна', u'REGION': u'Область', u'PCODE': u'Индекс', u'STREET': u'Адрес', u'NUMBER': u'Телефон', u'FAX': u'Факс', u'N': u'ФИО', u'NICKNAME': u'Ник', u'GIVEN': u'Имя', u'FAMILY': u'Фамилия', u'ORG': u'Организация', u'ORGNAME': u'Наименование', u'ORGUNIT': u'Отдел', u'HOME': u'Дом', u'CELL': u'Сотовый', u'FN': u'ФИ', u'MIDDLE': u'Отчество' }

#---------------------------------------------------------------------------------------------------

def vcard_run ( ptype, psource, pparameters ):
	global VCARD_PENDING

	liq = xmpp.Iq('get')
	lid = 'vcard' + str(random.randrange(1000, 9999))
	VCARD_PENDING.append(lid)
	liq.setID(lid)
	liq.addChild('vCard', { }, [ ], 'vcard-temp');

	lparam = pparameters.split()
	if len(lparam) == 1:
		if GROUPCHATS.has_key(psource[1]):
			if lparam[0] not in GROUPCHATS[psource[1]].keys():
				reply(ptype, psource, u'что-то я его не вижу :(')
				return
			else:
				if GROUPCHATS[psource[1]][lparam[0]]['ishere'] == 0:
					reply(ptype, psource, u'убежал он... *PARDON*')
					return
			liq.setTo(psource[1] + u'/' + lparam[0])
			JCON.SendAndCallForResponse(liq, vcard_answer, { 'ptype': ptype, 'psource': psource, 'pnick': lparam[0] })
		else:
			reply(ptype, psource, u'это возможно только в конференции...')
			return
	elif len(lparam) > 1:
		reply(ptype, psource, u'не понимаю я тебя... *PARDON*')
		return
	else:
		liq.setTo(psource[1] + u'/' + psource[2])
		JCON.SendAndCallForResponse(liq, vcard_answer, { 'ptype': ptype, 'psource': psource, 'pnick': psource[2] })

#---------------------------------------------------------------------------------------------------

def vcard_answer ( pcoze, pres, ptype, psource, pnick ):
	global VCARD_PENDING

	lid = pres.getID()
	if lid in VCARD_PENDING:
		VCARD_PENDING.remove(lid)
	else:
		reply(ptype, psource, u'что то не так... *SCRATCH*')
		return

	lanswer = u''
	if pres.getType() == 'error':
		if pnick == psource[2]:
			lanswer = u'хехе, твой клиент ничего не знает про вкарды'
		else:
			lanswer = u'хехе, его клиент ничего не знает про вкарды'

	elif pres.getType() == 'result':
		if len(pres.getChildren()) == 0:
			if pnick == psource[2]:
				reply(ptype, psource, u'вкард заполни сначала')
				return
			else:
				reply(ptype, psource, u'пусть он сначала свой вкард заполнит')
				return
		if pnick == psource[2]:
			lanswer = u'Про тебя я знаю следующее: '
		else:
			lanswer = u'Про %s я знаю следующее: ' % pnick
		ldict = vcard_xmltodict(pres.getChildren())
		lanswer += u'>>>' + vcard_dicttostr(ldict, 0)

	else:
		lanswer = u'зашифровался он... :-('

	reply(ptype, psource, lanswer)

#---------------------------------------------------------------------------------------------------

###
# Парсим xml преобразуя его в словарь
#
# param [ pitems ] >>> Набор xml nodes для анализа
#
# return >>> Словарь с данными
#     Так как возвращаемые данные в тегах могут иметь не только данные, но и другие теги,
#     то структура словаря по тегу имеет следующий формат:
#         {
#             <тег>: {
#                 <индекс>: { 0: <данные>, 1: { <вложенные теги> } },
#                 ...
#                 <индекс>: { 0: <данные>, 1: { <вложенные теги> } }
#             },
#             ...
#             <тег>: {
#                 <индекс>: { 0: <данные>, 1: { <вложенные теги> } },
#                 ...
#                 <индекс>: { 0: <данные>, 1: { <вложенные теги> } }
#             }
#         }
#     Если вложенные теги отсутствуют, то ключ 1 будет отсутствовать в словаре
###
def vcard_xmltodict ( pitems ):
	ldict = { }
	for litem in pitems:
		lname = litem.getName()
		if lname not in VCARD_OFF:
			if lname not in VCARD_EXCEPTION[u'list']:
				if ldict.has_key(lname):
					lindex = len(ldict[lname].keys())
				else:
					lindex = 0
					ldict[lname]= { }
				ldict[lname][lindex] = { 0: litem.getData() }
				if len(litem.getChildren()) != 0:
					ldict[lname][lindex][1] = vcard_xmltodict(litem.getChildren())
					if len(ldict[lname][lindex][1].keys()) == 0:
						del ldict[lname][lindex][1]

			else:
				if len(litem.getChildren()) != 0:
					ltemp = vcard_xmltodict(litem.getChildren())
					for lkey in VCARD_EXCEPTION[u'keys']:
						if lkey in ltemp.keys():
							lname = lkey
							del ltemp[lname]
							break

					for lkey in VCARD_EXCEPTION[u'line'].keys():
						if lkey in ltemp.keys() and VCARD_EXCEPTION[u'line'][lkey] in ltemp.keys():
							ltemp[lkey] = ltemp[VCARD_EXCEPTION[u'line'][lkey]]
							del ltemp[VCARD_EXCEPTION[u'line'][lkey]]

					if ldict.has_key(lname):
						lindex = len(ldict[lname].keys())
					else:
						lindex = 0
						ldict[lname]= { }
					ldict[lname][lindex] = { 0: litem.getData() }
					ldict[lname][lindex][1] = ltemp
					if len(ldict[lname][lindex][1].keys()) == 0:
						del ldict[lname][lindex][1]

	return ldict

#---------------------------------------------------------------------------------------------------

###
# Парсим словарь и преобразовываем его в строку, адаптированную для вывода
#
# param [ pdict  ] >>> Словарь с данными
# param [ plevel ] >>> Уровень вложенности
#
# return >>> Отформатированная строка с содержанием словаря
###
def vcard_dicttostr ( pdict, plevel ):
	lanswer = u''
	for litem in pdict.keys():
		lname = litem
		if VCARD_REPLACE.has_key(lname):
			lname = VCARD_REPLACE[lname]

		for ltag in pdict[litem]:
			ltemp = u''

			if len(pdict[litem][ltag][0]) != 0 or pdict[litem][ltag].has_key(1):
				if pdict[litem][ltag].has_key(1):
					if ltag == 0:
						lindent  = u'{:<%d}' % ( plevel * 4 )
						ltemp += u'\n' + lindent.format(u'') + u'%s:' % lname
					if len(pdict[litem][ltag][0]) != 0:
						lindent  = u'{:<%d}' % ( plevel * 8 )
						ltemp += u'\n' + lindent.format(u'') + u'%s' % pdict[litem][ltag][0]
				else:
					lindent  = u'{:<%d}' % ( plevel * 4 )
					ltemp += u'\n' + lindent.format(u'') + u'%s: %s' % ( lname, pdict[litem][ltag][0] )

			if pdict[litem][ltag].has_key(1):
				lresult = vcard_dicttostr(pdict[litem][ltag][1], plevel + 1)
				if len(lresult) != 0:
					ltemp += lresult
				else:
					ltemp = u''

			lanswer += ltemp

	return lanswer

#---------------------------------------------------------------------------------------------------

register_command_handler(vcard_run, 'визитка', [ 'мук', 'инфо', 'все' ], 10, 'Показывает vCard указанного пользователя', 'визитка [ник]', [ 'визитка Nick', 'визитка' ])
register_command_handler(vcard_run, 'вкард', [ 'мук', 'инфо', 'все' ], 10, 'Показывает vCard указанного пользователя', 'вкард [ник]', [ 'вкард Nick', 'вкард' ])

#---------------------------------------------------------------------------------------------------
